Welcome back to CS50’s Introduction to Programming with R!
Today, we will be learning about packaging and distributing our programs. This way, we can share them with the world!
dir.create("ducksay")
setwd("ducksay")
DESCRIPTION
NAMESPACE
man/
R/
tests/
Package: ducksay
Title: Duck Say
Description: Say hello with a duck.
Version: 1.0
Authors@R: person("Carter", "Zenke", email = "carter@cs50.harvard.edu", role = c("aut", "cre", "cph"))
License: MIT + file LICENSE
# Demonstrates adding on to a license template
YEAR: ...
COPYRIGHTHOLDER: ducksay authors
# Demonstrates suggesting a dependency, for testing's sake
Package: ducksay
Title: Duck Say
Description: Say hello with a duck.
Version: 1.0
Authors@R: person("Carter", "Zenke", email = "carter@cs50.harvard.edu", role = c("aut", "cre", "cph"))
License: MIT + file LICENSE
Suggests:
testthat (>= 3.0.0)
Config/testthat/edition: 3
Notice that the package will suggest that one should have testthat version 3.0.0 or above installed. This may vary depending on the version of testthat that you’ve installed.
# Demonstrates describing behavior of `ducksay`
describe("ducksay()", {
it("can print to the console with `cat`", {
expect_output(cat(ducksay()))
})
it("can say hello to the world", {
expect_match(ducksay(), "hello, world")
})
})
Notice that expect_match looks for the string hello, world in the output of ducksay.
# Demonstrates defining a function for a package
ducksay <- function() {
paste(
"hello, world",
">(. )__",
" (____/",
sep = "\n"
)
}
# Demonstrates declaring `ducksay` accessible to package end users
export(ducksay)
This file simply makes the ducksay function available to the end user of the package.
# Demonstrates checking for duck in output
describe("ducksay()", {
it("can print to the console with `cat`", {
expect_output(cat(ducksay()))
})
it("can say hello to the world", {
expect_match(ducksay(), "hello, world")
})
it("can say hello with a duck", {
duck <- paste(
">(. )__",
" (____/",
sep = "\n"
)
expect_match(ducksay(), duck, fixed = TRUE)
})
})
Notice how this test looks to see if a duck is represented. Additionally, notice how fixed = TRUE, as described in the lecture, prevents the test from misinterpreting some of the characters within the duck as being part of something called a regular expression. Suffice to say for now, a regular expression is not what we’d like!
We can now document how to use our function. Typically, we can type ?ducksay to see documentation. However, we have not created our documentation yet. Documentation is written in a type of language called a markup language. A markup language provides syntax for specifying the formatting of a document. *You can write your documentation by typing:
dir.create("man")
file.create("man/ducksay.Rd")
The first command creates a folder called man. The second creates our documentation file. *Modify your documentation file as follows:
# Demonstrates required markup for R documentation files
\name{ducksay}
\alias{ducksay}
\title{Duck Say}
\description{A duck that says hello.}
\usage{
ducksay()
}
\value{
A string representation of a duck saying hello to the world.
}
\examples{
cat(ducksay())
}
Notice how the name, title, description, usage, and other sections are provided. You can learn more about these elements by reading the documentation on R documentation files.
{ eval = FALSE} build R CMD build Notice that build is a
devtools function and can be run directly from the R console. R CMD
build can be run from the computer’s terminal outside of R. *Running
build, you will see a .gz file will be outputted within your working
directory.# Demonstrates ensuring duck repeats given phrase
describe("ducksay()", {
it("can print to the console with `cat`", {
expect_output(cat(ducksay()))
})
it("can say hello to the world", {
expect_match(ducksay(), "hello, world")
})
it("can say hello with a duck", {
duck <- paste(
">(. )__",
" (____/",
sep = "\n"
)
expect_match(ducksay(), duck, fixed = TRUE)
})
it("can say any given phrase", {
expect_match(ducksay("quack!"), "quack!")
})
})
Notice that a new test is added that looks for “quack!”
# Demonstrates taking an argument to print
ducksay <- function(phrase = "hello, world") {
paste(
phrase,
">(. )__",
" (____/",
sep = "\n"
)
}
Notice that a default phrase, “hello, world” is provided. If another phrase is provided, it will say that phrase instead.
# Demonstrates updated markup, including specifying arguments
\name{ducksay}
\alias{ducksay}
\title{Duck Say}
\description{A duck that says hello.}
\usage{
ducksay(phrase = "hello, world")
}
\arguments{
\item{phrase}{The phrase for the duck to say.}
}
\value{
A string representation of a duck saying the given phrase.
}
\examples{
cat(ducksay())
cat(ducksay("quack!"))
}
Notice that value is updated. Further, arguments is also updated. Another example is provided in examples.
We can run build again to include our modifications. This package can now be shared with others.
# Demonstrates using custom package
library(ducksay)
name <- readline("What's your name? ")
greeting <- ducksay(paste("hello,", name))
cat(greeting)
Notice that this program loads ducksay. Then, the code uses this new library.
install.packages
R CMD INSTALL
As discussed in previous lectures, the top command can be run directly within RStudio and is built into R itself. The other command can be run in the computer’s terminal. It is also built into R.
To install our package, we can run the following in our console: install.packages(“ducksay_1.0.tar.gz”)
You can share your code using CRAN, GitHub, and even email.
In this lesson, you learned how to package your programs in R. Specifically, you learned about: * Packages * Package Structure * devtools * Writing Tests * Writing R Code * NAMESPACE * Testing Code * Writing Documentation * Building Packages * Updating Packages * Using and Sharing Packages
In this course, you learned many things about R and programming with R. You learned how to represent data, transform data, apply functions, tidy data, visualize data, test programs, and package programs. In all, we hope that you have found this material helpful to you. We also hope that you will take what you have learned to do great good in the world.
This was CS50’s Introduction to Programming with R.